import pygame as pg
import os
from . import tool
from . import constants as c
from . import online
import socket


class MainMenu(tool.State):
    def __init__(self):
        tool.State.__init__(self)
    
    def startup(self, current_time, game_info):
        # 保存游戏信息
        self.game_info = game_info
        # 创建开始按钮和退出按钮
        self.setupButtons()
        
        # 创建游戏名称
        font = pg.font.SysFont(None, 50)
        self.name_image = font.render('My Strategy Game', True, c.SKY_BLUE, c.LIGHTYELLOW)
        self.name_rect = self.name_image.get_rect()
        # 设置游戏名称图形的位置
        self.name_rect.x = 200
        self.name_rect.y = 100

    def createButton(self, text, text_color, button_color, button_height):
        # 创建一个按钮图像，参数设置按钮的文字，文字颜色，按钮颜色，按钮的高度
        font_size = button_height
        font = pg.font.SysFont(None, font_size)
        text_image = font.render(text, True, text_color, button_color)
        text_rect = text_image.get_rect()

        image = pg.Surface([text_rect.w + 10, button_height])
        text_rect.centerx = image.get_rect().centerx
        text_rect.centery = image.get_rect().centery
        image.fill(button_color)
        image.blit(text_image, text_rect)
        return image

    def setupButtons(self):
        # 创建开始按钮
        self.start_image = self.createButton('Start Game', (26, 173, 25), (158, 217, 157), 50)
        self.start_rect = self.start_image.get_rect()
        # 设置开始按钮图形的位置
        self.start_rect.x = 240
        self.start_rect.y = 150

        # 创建线上按钮
        self.online_image = self.createButton('Online Game', (26, 173, 25), (158, 217, 157), 50)
        self.online_rect = self.online_image.get_rect()
        # 设置开始按钮图形的位置
        self.online_rect.x = 240
        self.online_rect.y = 250

        # 创建退出按钮
        self.quit_image = self.createButton('Quit Game', (230, 67, 64), (236, 139, 137), 50)
        self.quit_rect = self.quit_image.get_rect()
        # 设置退出按钮图形的位置
        self.quit_rect.x = 240
        self.quit_rect.y = 350

    def update(self, surface, current_time, mouse_pos, key_down):
        if mouse_pos is not None:
            # 有鼠标点击时，判断鼠标是否点击在按钮上
            x, y = mouse_pos
            if (x >= self.start_rect.x and x <= self.start_rect.right and
                y >= self.start_rect.y and y <= self.start_rect.bottom):
                # 点击开始按钮，设置下一个状态为关卡开始状态
                self.done = True
                self.next = c.LEVEL_START
            elif (x >= self.quit_rect.x and x <= self.quit_rect.right and
                y >= self.quit_rect.y and y <= self.quit_rect.bottom):
                self.done = True
                # 点击退出按钮，设置下一个状态为退出状态
                self.next = c.EXIT
            elif (x >= self.online_rect.x and x <= self.online_rect.right and
                y >= self.online_rect.y and y <= self.online_rect.bottom):
                self.done = True
                # 点击线上按钮，设置下一个状态为线上状态
                self.next = c.ONLINE_LOGIN

        # 绘制主菜单界面
        surface.fill(c.LIGHTYELLOW) # 改成图片
        surface.blit(self.name_image, self.name_rect)
        surface.blit(self.start_image, self.start_rect)
        surface.blit(self.online_image, self.online_rect)
        surface.blit(self.quit_image, self.quit_rect)

class Screen(tool.State):
    def __init__(self):
        tool.State.__init__(self)
        # 设置状态的结束定时器为 1 秒
        self.end_timer = 2000

    def startup(self, current_time, game_info):
        # 保存状态的开始时间
        self.start_time = current_time
        # 保存游戏信息
        self.game_info = game_info
        # 设置界面显示的文件图形
        self.setupTextImage()
        # 获取下一个状态
        self.next = self.getNextState()

    def setupTextImage(self):
        # 创建显示关卡信息的图形
        font = pg.font.SysFont(None, 50)

        # 根据游戏信息中的关卡值生成关卡信息
        level = 'Level - ' + str(self.game_info[c.LEVEL_NUM])
        self.level_image = font.render(level, True, c.SKY_BLUE, c.LIGHTYELLOW)
        self.level_rect = self.level_image.get_rect()
        # 设置关卡信息图形的位置
        self.level_rect.x = 170
        self.level_rect.y = 100
        
        self.text = self.getText()
        if self.text is not None:
            # 如果有文本信息，创建显示文本信息的图形
            font = pg.font.SysFont(None, 40)
            self.text_image = font.render(self.text, True, c.BLACK, c.LIGHTYELLOW)
            self.text_rect = self.text_image.get_rect()
            # 设置文本信息图形的位置
            self.text_rect.x = 180
            self.text_rect.y = 250

    def getNextState(self):
        # 返回下一个状态
        pass

    def getText(self):
        return None

    def update(self, surface, current_time, mouse_pos, key_down):
        if(current_time - self.start_time) < self.end_timer:
            # # 如果结束定时器没有超时，绘制界面
            surface.fill(c.LIGHTYELLOW)
            if self.text is not None:
                surface.blit(self.text_image, self.text_rect)
            else:
                surface.blit(self.level_image, self.level_rect)
        else:
            # 如果结束定时器超时，设置状态结束
            self.done = True

class LevelStartScreen(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):
        return c.LEVEL

class LevelLoseScreen(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):
        return c.MAIN_MENU

    def getText(self):
        return c.LEVEL_LOSE_INFO

class LevelWinScreen(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):

        if c.G_LOGINSTATE:
            return c.ONLINE_CONNECTED
        else:
            # 当前关卡胜利后，将关卡值加一
            self.game_info[c.LEVEL_NUM] += 1
            if self.game_info[c.LEVEL_NUM] <= c.MAX_LEVEL_NUM:
                return c.LEVEL_START
            else:
                # 如果已经是最后一个关卡了，则关卡值重设为初始关卡
                self.game_info[c.LEVEL_NUM] = c.START_LEVEL_NUM
                return c.MAIN_MENU

    def getText(self):
        return c.LEVEL_WIN_INFO

class ConnectFail(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):
        return c.MAIN_MENU

    def getText(self):
        return c.CONNECT_FAIL_INFO

class ConnectTimeout(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):
        return c.MAIN_MENU

    def getText(self):
        return c.CONNECT_TIMEOUT_INFO

class TextBox:
    def __init__(self, w, h, x, y, font=None):
        self.width = w
        self.height = h
        self.x = x
        self.y = y
        self.text = ""  # 文本框内容

        # 创建
        self.__surface = pg.Surface((w, h))
        # 如果font为None,那么效果可能不太好，建议传入font，更好调节
        if font is None:
            self.font = pg.font.Font(None, 32)  # 使用pygame自带字体
        else:
            self.font = font

    def draw(self, dest_surf):
        text_surf = self.font.render(self.text, True, (255, 255, 255))
        dest_surf.blit(self.__surface, (self.x, self.y))
        dest_surf.blit(text_surf, (self.x, self.y + (self.height - text_surf.get_height())),
                       (0, 0, self.width, self.height))

    def key_down(self, event):
        if event is None:
            return
        key = event.key
        # 退位键
        if key == pg.K_BACKSPACE:
            self.text = self.text[:-1]
        elif (key >= 48 and key <= 57) or (key >= 97 and key <= 122):
            char = chr(key)
            self.text += char
        return


class OnlineLogin(tool.State):
    def __init__(self):
        tool.State.__init__(self)

    def startup(self, current_time, game_info):

        # 保存游戏信息
        self.game_info = game_info

        self.active_box = 0
        self.text_box1 = TextBox(200, 30, 300, 200)
        self.text_box2 = TextBox(200, 30, 300, 300)

    def update(self, surface, current_time, mouse_pos, key_down):

        surface.fill(c.LIGHTYELLOW)

        # tab键
        if key_down is not None and key_down.key == pg.K_TAB:
            if self.active_box == 1:
                self.active_box = 0
            elif self.active_box == 0:
                self.active_box = 1

        if self.active_box == 0:
            self.text_box1.key_down(key_down)
        if self.active_box == 1:
            self.text_box2.key_down(key_down)

        font = pg.font.SysFont(None, 50)
        self.text1 = font.render('Login', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text1, [350, 100])
        self.text2 = font.render('Username', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text2, [100, 200])
        self.text3 = font.render('Password', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text3, [100, 300])
        self.text3 = font.render('Register', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text3, [200, 400])

        self.text_box1.draw(surface)
        self.text_box2.draw(surface)
        turn_image = pg.image.load(os.path.join("resources", "graphics", "button.png"))
        surface.blit(turn_image, [580, 350])

        if mouse_pos is not None:
            x, y = mouse_pos

            if (x >= 200 and x <= 400 and y >= 400 and y <= 500):
                self.done = True
                self.next = c.ONLINE_REGISTER

            if (x >= 600 and x <= 800 and y >= 300 and y <= 500):

                try:
                    s = socket.socket()
                    s.connect(('127.0.0.1', 6666))  # 与服务器建立连接
                    self.client = online.Client(s)
                    c.G_CLIENT = self.client
                    # 登录
                    self.client.login(self.text_box1.text, self.text_box2.text)

                    self.done = True
                    self.next = c.ONLINE_CONNECTING

                except:
                    self.done = True
                    self.next = c.ONLINE_CONNECTFAIL


class OnlineRegister(tool.State):

    def __init__(self):
        tool.State.__init__(self)

    def startup(self, current_time, game_info):

        # 保存游戏信息
        self.game_info = game_info

        self.active_box = 0
        self.text_box1 = TextBox(200, 30, 300, 200)
        self.text_box2 = TextBox(200, 30, 300, 300)
        self.text_box3 = TextBox(200, 30, 300, 400)

    def update(self, surface, current_time, mouse_pos, key_down):

        surface.fill(c.LIGHTYELLOW)

        # tab键
        if key_down is not None and key_down.key == pg.K_TAB:
            if self.active_box == 0:
                self.active_box = 1
            elif self.active_box == 1:
                self.active_box = 2
            elif self.active_box == 2:
                self.active_box = 0

        if self.active_box == 0:
            self.text_box1.key_down(key_down)
        if self.active_box == 1:
            self.text_box2.key_down(key_down)
        if self.active_box == 2:
            self.text_box3.key_down(key_down)

        font = pg.font.SysFont(None, 50)
        self.text1 = font.render('Register', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text1, [350, 100])
        self.text2 = font.render('Username', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text2, [100, 200])
        self.text3 = font.render('Password', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text3, [100, 300])
        self.text3 = font.render('Nickname', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text3, [100, 400])

        self.text_box1.draw(surface)
        self.text_box2.draw(surface)
        self.text_box3.draw(surface)
        turn_image = pg.image.load(os.path.join("resources", "graphics", "button.png"))
        surface.blit(turn_image, [580, 350])

        if mouse_pos is not None:
            x, y = mouse_pos
            if (x >= 600 and x <= 800 and y >= 300 and y <= 500):

                try:
                    s = socket.socket()
                    s.connect(('127.0.0.1', 6666))  # 与服务器建立连接
                    self.client = online.Client(s)
                    c.G_CLIENT = self.client

                    self.client.register(self.text_box1.text, self.text_box2.text, self.text_box3.text)

                    self.done = True
                    self.next = c.ONLINE_CONNECTING

                except:
                    self.done = True
                    self.next = c.ONLINE_CONNECTFAIL


class OnlineConnecting(tool.State):

    def __init__(self):
        tool.State.__init__(self)
        self.end_timer = 5000


    def startup(self, current_time, game_info):
        # 保存状态的开始时间
        self.start_time = current_time
        self.game_info = game_info
        self.client = c.G_CLIENT

    def update(self, surface, current_time, mouse_pos, key_down):
        if (current_time - self.start_time) < self.end_timer:
            # # 如果结束定时器没有超时，绘制界面
            surface.fill(c.LIGHTYELLOW)
            font = pg.font.SysFont(None, 50)
            self.text1 = font.render('Connecting...', True, c.SKY_BLUE, c.LIGHTYELLOW)
            surface.blit(self.text1, [350, 100])

            if self.client.login_state is not None:
                if self.client.login_state == -1:
                    self.done = True
                    self.next = c.ONLINE_CONNECTFAIL
                elif self.client.login_state == 1:
                    self.done = True
                    self.next = c.ONLINE_CONNECTED

        else:
            # 如果结束定时器超时，设置状态结束
            self.done = True
            self.next = c.ONLINE_CONNECTTIMEOUT


class OnlineMenu(tool.State):

    def __init__(self):
        tool.State.__init__(self)

    def startup(self, current_time, game_info):
        # 保存游戏信息
        self.game_info = game_info

        # 创建游戏名称
        self.font = pg.font.SysFont(None, 50)
        self.name_image = self.font.render('Online Games', True, c.SKY_BLUE, c.LIGHTYELLOW)
        self.name_rect = self.name_image.get_rect()
        # 设置游戏名称图形的位置
        self.name_rect.x = 90
        self.name_rect.y = 100
        self.client = c.G_CLIENT
        self.game_state = [0, 0, 0, 0, 0, 0]
        self.game_id = [0, 0, 0, 0, 0, 0]
        self.rect = []
        for i in range(0, 6):
            self.rect.append([50 + 400 * (i % 2), 150 + 150 * int(i / 2), 300, 100])
        c.G_ACTIVEGAME = None
        self.renew()

    def renew(self):
        self.game_id = self.client.load_id()
        self.client.renew(self.game_id)

    def draw(self, surface):
        surface.fill(c.LIGHTYELLOW)
        box_color = {}
        box_text = {}
        for i in range(0, 6):
            if self.game_state[i] == 0:
                box_color[i] = c.LIGHTYELLOW
                box_text[i] = 'new game'
            elif self.game_state[i] == 1:
                box_color[i] = c.GREY
                box_text[i] = 'waiting to join'
            elif self.game_state[i] == 2:
                box_color[i] = c.GREEN
                box_text[i] = 'your turn!'
            elif self.game_state[i] == 3:
                box_color[i] = c.GREY
                box_text[i] = 'waiting to act'
            elif self.game_state[i] == 4:
                box_color[i] = c.GOLD
                box_text[i] = 'You win!'
            elif self.game_state[i] == 5:
                box_color[i] = c.RED
                box_text[i] = 'You Lose!'

        for i in range(0, 6):
            rect2 = [self.rect[i][0], self.rect[i][1]+50, self.rect[i][2], self.rect[i][3]]
            image1 = self.font.render(box_text[i], True, c.BLACK)
            image2 = self.font.render('id:'+str(self.game_id[i]), True, c.BLACK)
            pg.draw.rect(surface, box_color[i], self.rect[i], 0)
            pg.draw.rect(surface, c.BLACK, self.rect[i], 2)
            surface.blit(image1, [self.rect[i][0], self.rect[i][1]])
            if self.game_state[i] != 0:
                surface.blit(image2, [rect2[0], rect2[1]])

        font = pg.font.SysFont(None, 50)
        text = font.render('Welcome ' + self.client.player_name, True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(text, [300, 50])
        text = font.render('Back', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(text, [20, 550])
        text = font.render('Renew', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(text, [650, 20])

    def update(self, surface, current_time, mouse_pos, key_down):
        if self.client.renew_data is not None:
            self.game_state = self.client.renew_data
        if mouse_pos is not None:
            x, y = mouse_pos
            for i in range(0, 6):
                if (x >= self.rect[i][0] and x <= self.rect[i][0]+self.rect[i][2] and
                        y >= self.rect[i][1] and y <= self.rect[i][1]+self.rect[i][3]):
                    if self.game_state[i] == 0:
                        c.G_ACTIVEBOX = i
                        self.done = True
                        self.next = c.ONLINE_NEWGAME
                    elif self.game_state[i] == 2:
                        game = self.client.findplayer(self.client.player_name)
                        c.G_ACTIVEBOX = i
                        c.G_ACTIVEGAME = game['game_info'][i]
                        self.client.load(self.client.player_name, game['game_info'][i]['game_id'])
                        self.done = True
                        self.next = c.ONLINE_LEVEL_START
                    elif self.game_state[i] == 4 or self.game_state[i] == 5:
                        self.client.clear_data(i)
                        self.game_state[i] = 0

            if (x >= 0 and x <= 150 and y >= 500 and y <= 600):
                self.done = True
                self.client.logout()
                self.next = c.MAIN_MENU

            if (x >= 700 and x <= 800 and y >= 0 and y <= 100):
                self.renew()

        self.draw(surface)


class OnlineStartScreen(Screen):
    def __init__(self):
        Screen.__init__(self)

    def setupTextImage(self):
        # 创建显示关卡信息的图形
        font = pg.font.SysFont(None, 50)
        self.client = c.G_CLIENT

        # 根据游戏信息中的关卡值生成关卡信息
        level = 'game with ' + str(self.client.opponent_name)
        self.level_image = font.render(level, True, c.SKY_BLUE, c.LIGHTYELLOW)
        self.level_rect = self.level_image.get_rect()
        # 设置关卡信息图形的位置
        self.level_rect.x = 170
        self.level_rect.y = 100

        self.text = None

    def getNextState(self):
        return c.LEVEL


class OnlineUploading(Screen):
    def __init__(self):
        Screen.__init__(self)

    def getNextState(self):
        return c.ONLINE_CONNECTED

    def getText(self):
        return c.UPLOAD_INFO


class OnlineNewgame(tool.State):
    def __init__(self):
        tool.State.__init__(self)

    def startup(self, current_time, game_info):

        # 保存游戏信息
        self.game_info = game_info
        self.text_box1 = TextBox(400, 30, 200, 150)
        self.client = c.G_CLIENT

    def update(self, surface, current_time, mouse_pos, key_down):

        surface.fill(c.LIGHTYELLOW)
        self.text_box1.key_down(key_down)

        font = pg.font.SysFont(None, 50)
        self.text1 = font.render('Join game', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text1, [200, 400])
        self.text2 = font.render('game id:', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text2, [200, 200])
        self.text3 = font.render('New game', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text3, [450, 400])
        self.text4 = font.render('Back', True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(self.text4, [20, 520])

        self.text_box1.draw(surface)

        if mouse_pos is not None:
            x, y = mouse_pos

            if (x >= 200 and x <= 350 and y >= 400 and y <= 500):
                self.client.join(self.text_box1.text)
                self.done = True
                self.next = c.ONLINE_CONNECTED

            if (x >= 450 and x <= 600 and y >= 400 and y <= 500):
                self.client.newgame()
                self.done = True
                self.next = c.ONLINE_CONNECTED

            if (x >= 0 and x <= 150 and y >= 500 and y <= 600):
                self.done = True
                c.G_ACTIVEBOX = None
                self.next = c.ONLINE_CONNECTED

